# -*- coding: utf-8 -*-
__author__ = 'lztkdr'
__date__ = '2019/7/10 21:17'

'''
selenium浏览器驱动
'''

from selenium import webdriver
from enum import Enum
import os
from fake_useragent import UserAgent


def driver_headless(type="firefox", headless=False,driver_path="geckodriver.exe"):
    '''
    创建浏览器驱动（支持有头和无头）
    :param type:  浏览器类别
    :param headless: True -- 无头拉起浏览器（后台执行）,False：有头（前台拉起浏览器执行）
    :param driver_path: 驱动路径,此处我把geckodriver.exe放到虚拟环境下面后，可以不加driver_path
    :return: driver
    '''
    driver = None
    if type == "firefox":
        FirefoxOpt = webdriver.FirefoxOptions()
        if headless:
            FirefoxOpt.add_argument("--headless")  #设置firefox浏览器为无头
        #设置UA代理选项
        FirefoxOpt.add_argument('user-agent="Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20"')
        driver = webdriver.Firefox(executable_path=driver_path, firefox_options=FirefoxOpt)
    elif type == "ie":
        ie_opt = webdriver.IeOptions()
        if headless:
            ie_opt.add_argument("--headless")
        driver = webdriver.Ie(executable_path=driver_path, ie_options=ie_opt)
    return driver


class driverType(Enum):
    """
    浏览器类型
    """
    Chrome = 0
    Firefox = 1
    IE = 2
    Edge = 3

class deviceType(Enum):
    """
    设备类型
    """
    PC = 0,
    Pad = 1
    Mobile = 2


def get_driver(homePage,proxyHost = None,headless = False, device_type = deviceType.PC, autoOpenDevTools = False, driver_type = driverType.Chrome):
    """
    获取一个浏览器web驱动器
    :param homePage:默认打开的url页面
    :param proxyHost:代理主机，一般为：IP:Port
    :param headless:是否无头模式
    :param device_type: 要模拟的设备类型（PC,Pad,Mobile）
    :param autoOpenDevTools: 是否自动打开开发人员工具
    :param driver_type:浏览器类型
    :return:返回 webdriver
    """
    driver = None
    opt = None
    profile = None
    capabilities = None
    driver_path = None
    ip = None
    port = None

    UserData_Dir = "userdata_default"
    if not os.path.exists(UserData_Dir):
        os.makedirs(UserData_Dir)

    if proxyHost:
        strs = proxyHost.split(":")
        ip = strs[0]
        # 端口 必须是 int 类型！！！
        port = int(strs[1])

    ua = UserAgent()

    if driver_type == driverType.Firefox:
        opt = webdriver.FirefoxOptions()
        driver_path = "geckodriver.exe"
        profile = webdriver.FirefoxProfile()
        #加快 访问没有证书的https站点 的访问速度
        profile.assume_untrusted_cert_issuer = True
        profile.accept_untrusted_certs = True

        if proxyHost:
            #配置 firefox 代理
            profile.set_preference('network.proxy.type', 1)
            #普通http请求
            profile.set_preference('network.proxy.http', ip)
            profile.set_preference('network.proxy.http_port', port)
            #如果要爬取 https 链接，也需设置 ssl
            profile.set_preference('network.proxy.ssl', ip)
            profile.set_preference('network.proxy.ssl_port', port)

        # 伪装 user-agent
        profile.set_preference("general.useragent.override",ua.firefox)


        if homePage:
            # 0空白首页设置不生效  1用户自定义首页
            profile.set_preference("browser.startup.page", 1)
            profile.set_preference("browser.startup.homepage",homePage)

        if autoOpenDevTools:
            opt.add_argument("-devtools")

    elif driver_type == driverType.Chrome:
        opt =  webdriver.ChromeOptions()
        driver_path = "chromedriver.exe"

        if proxyHost:
            capabilities = opt.to_capabilities()
            capabilities['acceptSslCerts'] = True
            capabilities['acceptInsecureCerts'] = True
            capabilities['proxy'] = {
                "httpProxy": proxyHost,
                "ftpProxy": proxyHost,
                "sslProxy": proxyHost,
                "proxyType": "MANUAL",
                "autodetect": False,
            }

        # 伪装 user-agent
        opt.add_argument(f'user-agent={ua.chrome}')

        if homePage:
            opt.add_argument(f"--homepage {homePage}")
        if autoOpenDevTools:
            opt.add_argument(f"--auto-open-devtools-for-tabs")

        # 防止浏览器检测 window.navigator.webdriver = true ;
        opt.add_experimental_option('excludeSwitches', ['enable-automation'])

    elif driver_type == driverType.IE:
        opt = webdriver.IeOptions()
        driver_path = "IEDriverServer.exe"
        #TODO:IE浏览器的 其他配置
    elif driver_type == driverType.Edge:
        driver_path = "IEDriverServer.exe"
        # TODO:Edge浏览器的 其他配置

    if headless:
        opt.add_argument("--headless")
        #禁用插件
        # opt.add_argument("--disable-plugins")


    #禁用图片,提升响应速度
    # opt.add_argument("--disable-images")
    # opt.add_argument("blink-settings=imagesEnabled=false")
    # profile.set_preference("profile.default_content_setting_values.images",2)

    if driver_type == driverType.Chrome:
        # 指定用户数据目录，可以防止打开chrome浏览器 自动出现  data; 页签
        if UserData_Dir:
            opt.add_argument(f"--user-data-dir={UserData_Dir}")

        #禁止chrome 浏览器 显示被测试软件控制
        opt.add_argument("--disable-infobars")
        # 禁用弹出拦截
        opt.add_argument("--disable-popup-blocking")
        # 启动无沙盒模式运行
        opt.add_argument("--no-sandbox")
        # 禁用gpu
        opt.add_argument("--disable-gpu")
        # 忽略证书错误
        opt.add_argument("--ignore-certificate-errors")
        # 禁用翻译
        opt.add_argument("--disable-translate")
        #防止出现：unknown error: DevToolsActivePort file doesn't exist
        opt.add_argument("--disable-dev-shm-usage")
        #禁用通知
        opt.add_argument("--disable-notifications")

        if device_type == deviceType.PC:
            opt.add_argument("--start-maximized")
        elif device_type == deviceType.Pad:
            opt.add_experimental_option("mobileEmulation",{'deviceName': 'iPad'})
        elif device_type == deviceType.Mobile:
            opt.add_experimental_option("mobileEmulation", {'deviceName': 'iPhone X'})
        else:
            opt.add_argument("--start-maximized")
    else:
        # TODO:其他浏览器 设备模拟方式
        pass
    if driver_type == driverType.Chrome:
        driver = webdriver.Chrome(executable_path = driver_path, options = opt, desired_capabilities = capabilities)
    elif driver_type == driverType.Firefox:
        driver = webdriver.Firefox(executable_path = driver_path, firefox_options = opt,firefox_profile = profile, capabilities = capabilities)
    elif driver_type == driverType.IE:
        driver = webdriver.Ie(executable_path = driver_path, options = opt)
    elif driver_type == driverType.Edge:
        driver = webdriver.Edge(executable_path = driver_path, capabilities = capabilities)
    return driver



